/*
 * CEV: sistema open-source para voteções institucionais
 * Copyright (C) 2009, 2010, 2011 Skynet Coders @ Universidade Estadual de Feira de Santana
 *
 * Este arquivo é parte do programa CEV.
 *
 * CEV é um software livre; você pode redistribui-lo e/ou modifica-lo
 * dentro dos termos da Licença Pública Geral GNU (GNU GPL) como publicada
 * pela Fundação do Software Livre (FSF) na versão 3 da Licença.
 *
 * Este programa é distribuido na esperança que possa ser util, mas
 * SEM NENHUMA GARANTIA; sem uma garantia implicita de ADEQUAÇÂO a qualquer
 * MERCADO ou APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU para
 * maiores detalhes.
 *
 * Você deve ter recebido uma cópia da Licença Pública Geral GNU
 * junto com este programa, se não, escreva para a Fundação do Software
 * Livre(FSF) Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <QFile>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>
#include <QtSql/QSqlDatabase>
#include "QVariant"
#include "QVariantList"
#include <QStringList>
#include <QCoreApplication>
#include <QDebug>
#include <exception>
#include "database.h"

/**
  * Empty constructor
  */
Database::Database(){
    return;
}

Database::~Database(){

    this->closeDatabase();
}

/**
  @abstract Create the CEV database
  @return bool
  */
bool Database::create(){
    /* beginning of initialization*/
    this->databaseName = QCoreApplication::applicationDirPath() + "/resources/cev.db";
    this->databaseDriver = "QSQLITE";
    if(this->databaseExists())
    {
        qDebug() << "Database " +this->databaseName +" Exists!";
    }
    this->connectionName = "cev_sqlite";
    this->connection = QSqlDatabase::addDatabase(this->databaseDriver, this->connectionName);
    this->connection.setDatabaseName(databaseName);
    this->connection.open();
    /* end of initialization*/
    if(!this->connection.isOpen())
    {
        return false;
    }
    try
    {
        // setup table
        if(!this->setupTable())
            throw new exception;
    }
    catch (exception e)
    {
        qDebug() << "Could not setup table correcty.";
        //this->closeDatabase();
    }

    // close connection
    this->closeDatabase();
    return true;
}

/**
  @abstract Checks if the database file currently exists
  @return bool
  */
bool Database::databaseExists()
{
    return QFile::exists(this->databaseName);
}

/**
  @abstract Deletes the database file.
  @return bool
  */
bool Database::deleteDatabase()
{
    if (!this->closeDatabase()){
        return false;
    }
    QFile databaseFile(this->databaseName);
    if (!databaseFile.remove()){
        qDebug() << databaseFile.errorString();
        return false;
    }
    return true;
}


/**
  @abstract Create and setup the users table.
  @return bool
  */
bool Database::setupTable(){
    this->sqlTable = "CREATE table if not exists users"
            "("
            "id integer primary key autoincrement, "
            "name text, "
            "registration text, "
            "description text, "
            "login text, "
            "password text, "
            "type text"
            ");";

    QSqlQuery query = QSqlQuery(this->connection);
    if (!query.exec(this->sqlTable)){
        qDebug() << query.lastError();
        return false;
    }       
    qDebug() << "[INFO] Tables successfully created.";

    // begin indexes setup
    QString sql;
    sql = "create unique index if not exists idx_usernames on users(name);";
    if (!query.exec(sql)){
        qDebug() << query.lastError();
        return false;
    }

    sql = "create unique index if not exists idx_userregistration on users(registration);";
    if (!query.exec(sql)){
        qDebug() << query.lastError();
        return false;
    }

    sql = "create unique index if not exists idx_userlogin on users(login);";
    if (!query.exec(sql)){
        qDebug() << query.lastError();
        return false;
    }
    qDebug() << "[INFO] Indexes successfully created.";
    // end indexes setup

    return true;
}


/**
  @abstract Closes the database
  @return bool
  */
bool Database::closeDatabase(){
        this->connection.close();
        QSqlDatabase::removeDatabase(this->connectionName);
        if(this->connection.isOpen()){
            qDebug()  << this->connection.lastError();
            return false;
        }
        return true;

}
